package com.netty.tcp.nettyService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.netty.tcp.ew.domain.*;
import com.netty.tcp.ew.service.IBaseAreaService;
import com.netty.tcp.ew.service.PortReDataService;
import com.netty.tcp.ew.service.PortReceiveService;
import com.netty.tcp.ew.service.StationService;
import com.netty.tcp.common.DateUtil;
import com.netty.tcp.redis.RedisCache;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author hzj
 * @date 2020/12/31 15:21
 */
@Component
@Log4j2
@ChannelHandler.Sharable
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    @Autowired
    private IBaseAreaService baseAreaService;
    @Autowired
    private RedisCache redisCache;

    public static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    private JedisPool jedisPool =  new JedisPool(new JedisPoolConfig(), "localhost", 13521,0,"wujunlei");
    private Jedis jedis = jedisPool.getResource();

    /**
     * 客户端连接会触发
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.add(channel);
        log.info("服务器接收到客户端登录信息: {}", channel.toString());
        System.out.println(channel.remoteAddress() + " 上线," + "在线数量：" + channelGroup.size());
    }

    /**
     * 客户端发消息会触发
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Channel channel = ctx.channel();
        switch (msg.toString().length()){
            case 30:
                redisCache.setCacheObject(hexStringToString(msg.toString()),channel.id(),130,TimeUnit.SECONDS);// 将16进制的IMEI转为字符串后，写入redis在线设备列表,有效期100秒，比心跳多2秒
                redisCache.setCacheObject(channel.id().toString(),hexStringToString(msg.toString()),130,TimeUnit.SECONDS);// 将16进制的IMEI转为字符串后，写入redis在线设备列表,有效期100秒，比心跳多2秒
                log.info("[服务器收到注册信息]-" + hexStringToString(msg.toString()) + "已经上线"+"\n");
                break;
            default:
                log.info("[服务器收到返回信息]-" + (msg.toString()) + "已存入队列"+"\n");
                String sourceIot = redisCache.getCacheObject(channel.id().toString());
                JSONObject json = new JSONObject();
                json.put("sourceIot",sourceIot);
                json.put("message", msg.toString());
                jedis.rpush("receiveMessage",json.toString());//将需要解析的数据先收到队列中
                break;
        }
//        BaseArea baseArea = new BaseArea();
//        baseArea.setCompanyId(3);
//        List<BaseArea> baseAreaList = listarea(baseArea);
//        for (BaseArea b : baseAreaList ){
////            ctx.writeAndFlush(b.toString());
//            redisCache.setCacheObject(b.getAreaId().toString(),b.getAreaId().toString());
//            ctx.writeAndFlush(redisCache.getCacheObject(b.getAreaId().toString())+"-");
//
//        }
//        redisCache.setCacheObject("good",msg.toString());
//        ctx.writeAndFlush(redisCache.getCacheObject("good"));
//        redisCache.setCacheObject("netty",msg.toString());
//        ctx.writeAndFlush(msg.toString());


    }

    /**
     * 发生异常触发
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
        log.info("[发生异常]-");
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception{
//        Channel channel = ctx.channel();
//        channelGroup.add(channel);
////        redisCache.setCacheMapValue("client",channel.id().toString(),channel.id());
//        redisCache.setCacheObject(channel.id().toString(),channel.id());
//
//        log.info("companylete");
    }

    //断开连接
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.remove(channel);
        redisCache.deleteObject(channel.id().toString());

        log.info("断开连接.................");
    }
    @Transactional
    public List<BaseArea> listarea(BaseArea baseArea){
        List<BaseArea> list = baseAreaService.selectBaseAreaList(baseArea);
        return list;
    }

    public byte[] hexString2Bytes(String src) {
        int l = src.length() / 2;
        byte[] ret = new byte[l];
        for (int i = 0; i < l; i++) {
            ret[i] = (byte) Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();
        }
        return ret;
    }

    /**
     * 16进制转换成为string类型字符串
     * @param s
     * @return
     */
    public static String hexStringToString(String s) {
        if (s == null || s.equals("")) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "UTF-8");
            new String();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }

}
